package plat

import (
	"encoding/json"
	"errors"
	"fmt"
	"strings"
	"time"

	"bytes"

	"strconv"

	"publish/app/account/model"
	"github.com/PuerkitoBio/goquery"
)

var (
	//最大90天
	qier_profit     = "/account/incomeDetail?beginDate=%s&endDate=%s&relogin=1"
	qier_profit_new = "/income/GetUserIncomeList?from=%s&to=%s"

	//不限天数
	qier_index      = "/omIndex/getIndexTrend?beginDate=%s&endDate=%s&relogin=1"
	qier_news_stat  = "/statistic/mediaDaily?channel=0&btime=%d&etime=%d&page=%d&num=1000&relogin=1"
	qier_video_stat = "/VideoData/MediaDailyStatis?startdate=%s&enddate=%s&fields=2%7C3&source=1%7C2%7C3%7C4%7C5%7C-1&relogin=1"
)

func init() {
	RegisterPlat("QIER", newplat_qier())
}

type platqier struct {
	*plathttp
}

func newplat_qier() Plat {
	return &platqier{
		plathttp: &plathttp{
			Host: "https://om.qq.com",
		},
	}
}

func (p *platqier) GetProfit(account *model.Account, start, end time.Time) ([]AccountProfit, error) {
	start_s := start.Format("2006-01-02")
	end_s := end.Format("2006-01-02")
	if strings.Compare(end_s, "2018-01-08") < 0 {
		return p.GetProfitOld(account, start, end)
	} else if strings.Compare("2018-01-07", start_s) < 0 {
		return p.GetProfitNew(account, start, end)
	} else {
		day_s, _ := time.Parse("2006-01-02 MST", "2018-01-08 CST")
		day_e, _ := time.Parse("2006-01-02 MST", "2018-01-07 CST")
		ret1, err := p.GetProfitNew(account, day_s, end)
		if err != nil {
			return nil, err
		}

		ret2, err := p.GetProfitOld(account, start, day_e)
		if err != nil {
			return nil, err
		}
		return append(ret1, ret2...), nil
	}
}

func (p *platqier) GetProfitNew(account *model.Account, start, end time.Time) ([]AccountProfit, error) {
	p.setCookie(account.GetCookie())
	uk := fmt.Sprintf(qier_profit_new, start.Format("2006-01-02"), end.Format("2006-01-02"))
	body, err := p.getReq(p.url(uk), "Referer", p.url("/income/incomeStatistic"), "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, err
	}

	var data QierProfitResp
	if err := json.Unmarshal(body, &data); err != nil {
		return nil, err
	}

	if data.Code != 0 {
		return nil, errors.New(fmt.Sprintf("get profit return , account_id = %d, errorms = %s", account.Id, data.Msg))
	}

	rets := make([]AccountProfit, 0)
	for _, profit := range data.Data {
		if profit.TotalAmount.String() == "--" {
			continue
		}
		total, _ := profit.TotalAmount.Float64()
		rets = append(rets, AccountProfit{
			AccountId: account.Id,
			Profit:    total,
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      profit.Date,
		})
	}
	return rets, nil
}

func (p *platqier) GetProfitOld(account *model.Account, start, end time.Time) ([]AccountProfit, error) {
	p.setCookie(account.GetCookie())
	uk := fmt.Sprintf(qier_profit, start.Format("2006-01-02"), end.Format("2006-01-02"))
	body, err := p.getReq(p.url(uk), "Referer", p.url("/supplier/incomeStatistic"), "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, err
	}

	var data QierProfitResp
	if err := json.Unmarshal(body, &data); err != nil {
		return nil, err
	}

	if data.Code != 0 {
		return nil, errors.New(fmt.Sprintf("get profit return , account_id = %d, errorms = %s", account.Id, data.Msg))
	}

	rets := make([]AccountProfit, 0)
	for _, profit := range data.Data {
		total, _ := profit.TotalAmount.Float64()
		rets = append(rets, AccountProfit{
			AccountId: account.Id,
			Profit:    total,
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      profit.Date,
		})
	}
	return rets, nil
}

func (p *platqier) GetIndex(account *model.Account, start, end time.Time) ([]AccountData, error) {

	p.setCookie(account.GetCookie())
	uk := fmt.Sprintf(qier_index, start.Format("2006-01-02"), end.Format("2006-01-02"))
	body, err := p.getReq(p.url(uk), "Referer", p.url("/data/index"), "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, err
	}

	indexs := QierIndexResp{}
	err = json.Unmarshal(body, &indexs)
	if err != nil {
		return nil, err
	}

	if indexs.Code != 0 {
		return nil, errors.New(fmt.Sprintf("get profit return , account_id = %d, errorms = %s", account.Id, indexs.Msg))
	}

	rets := make([]AccountData, 0)
	for _, index := range indexs.Data.Result {
		rets = append(rets, AccountData{
			AccountId: account.Id,
			Index:     index.Total.String(),
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      index.Date,
			IndexJson: map[string]interface{}{
				"total":      index.Total,
				"favorite":   index.Favorite,
				"creativity": index.Creativity,
				"activity":   index.Activity,
				"influence":  index.Influence,
				"reward":     index.Reward,
			},
		})
	}
	return rets, nil
}

func (p *platqier) GetEveryStatistic(account *model.Account,start,end time.Time)([]EveryDayStatisttic, error){
	return nil,nil
}

func (p *platqier) GetStatistic(account *model.Account, start, end time.Time) ([]AccountStatisttic, error) {
	datas := []AccountStatisttic{}
	news, err := p.getStatisticNews(account, start, end)
	if err != nil {
		fmt.Println("GetStatisticNews:", err.Error())
	} else {
		datas = append(datas, news...)
	}

	videos, err := p.getStatisticVideo(account, start, end)
	if err != nil {
		fmt.Println("GetStatisticVideo :", err.Error())
	} else {
		datas = append(datas, videos...)
	}

	return datas, err
}

func (p *platqier) getStatisticNews(account *model.Account, start, end time.Time) ([]AccountStatisttic, error) {
	rets := make([]AccountStatisttic, 0)
	page := 1
	for {
		vals, next, err := p.getStatisticNewsPage(account, start, end, page)
		if err != nil {
			return nil, err
		}
		if len(vals) > 0 {
			rets = append(rets, vals...)
		}
		if next <= 0 {
			break
		}
		page = next
	}
	return rets, nil
}

func (p *platqier) getStatisticNewsPage(account *model.Account, start, end time.Time, page int) ([]AccountStatisttic, int, error) {

	p.setCookie(account.GetCookie())
	uk := fmt.Sprintf(qier_news_stat, start.Unix(), end.Unix(), page)
	bodyBytes, err := p.getReq(p.url(uk), "Referer", p.url("/article/mediaStatistic"), "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, -1, err
	}
	fmt.Println(string(bodyBytes))
	statistic := QierStatisticResp{}
	err = json.Unmarshal(bodyBytes, &statistic)
	if err != nil {
		return nil, -1, err
	}
	datas := []AccountStatisttic{}
	for _, data := range statistic.Data.Statistic {
		datas = append(datas, AccountStatisttic{
			AccountId: account.Id,
			Num:       data.Read, //阅读量
			Type:      "reads_news",
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      data.StatisticDate,
		}, AccountStatisttic{
			AccountId: account.Id,
			Num:       data.Exposure, //推荐量
			Type:      "recommends_news",
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      data.StatisticDate,
		})
	}
	if page >= statistic.Data.TotalPage {
		return datas, -1, nil
	}
	return datas, page + 1, nil
}

func (p *platqier) getStatisticVideo(account *model.Account, start, end time.Time) ([]AccountStatisttic, error) {

	uk := p.url(fmt.Sprintf(qier_video_stat, start.Format("2006-01-02"), end.Format("2006-01-02")))

	p.setCookie(account.GetCookie())
	bodyBytes, err := p.getReq(uk, "Referer", p.url("/article/videoMediaStatistic"), "X-Requested-With", "XMLHttpRequest")
	if err != nil {
		return nil, err
	}
	statistic := QierVideoStatResp{}
	err = json.Unmarshal(bodyBytes, &statistic)
	if err != nil {
		return nil, err
	}
	datas := []AccountStatisttic{}
	for _, data := range statistic.Data.List {
		total, _ := data.NewDailyPlayPv.Int64()
		datas = append(datas, AccountStatisttic{
			AccountId: account.Id,
			Num:       total, //播放量
			Type:      "reads_video",
			Time:      time.Now().Format("2006-01-02 15:04:05"),
			Date:      data.Date,
		})
	}

	return datas, nil
}

func (p *platqier) GetLevel(account *model.Account) (string, error) {
	url := `https://om.qq.com/`

	p.setCookie(account.GetCookie())
	bodyBytes, err := p.getReq(url)
	if err != nil {
		return "", err
	}
	doc, err := goquery.NewDocumentFromReader(bytes.NewReader(bodyBytes))
	if err != nil {
		return "", err
	}
	level := doc.Find(".label-shenfen").Text()

	if level == "新手期" {
		return LEVEL_NEW, err
	}

	if strings.Contains(level, "企鹅号") {
		return LEVEL_MONEY, err
	}

	return "", nil
}


func (p *platqier) GetArticles(account *model.Account, start time.Time, end time.Time) ([]Article, error) {
	articles := []Article{}
	page := 1

	for {
		api := fmt.Sprintf(`https://om.qq.com/statistic/ArticleReal?page=%d&num=8&relogin=1`, page)
		p.setCookie(account.GetCookie())
		bodyBytes, err := p.getReq(api, "Referer", "https://om.qq.com/article/articleStatistic", "x-requested-with", "XMLHttpRequest")
		if err != nil {
			return nil, err
		}
		datas := QierList{}
		if err := json.Unmarshal(bodyBytes, &datas); err != nil {
			return nil, err
		}

		if len(datas.Data.Articles) == 0 {
			return articles, nil
		}

		for _, data := range datas.Data.Articles {
			statusMsg := "未知"
			status := 0

			t, _ := time.Parse("2006-01-02 15:04:05", data.Date)

			if t.Before(start) {
				return articles, nil
			}

			if t.Before(end) {
				articles = append(articles, Article{
					ArticleId: data.ArticleId,
					Title:   data.Title,
					Url:     data.Url,
					Time:    t,
					Status:  status,
					FailMsg: statusMsg,

					RecommentCount : data.RecommentCount,
					ReadCount: data.ReadCount,
					CommentCount: data.CommentCount,
					FavCount: data.FavCount,
				})
			}
		}

		page++
	}
	return articles, nil
}

func (p *platqier) GetPayRecord(account *model.Account, start time.Time, end time.Time) ([]PayRecord, error) {
	payRecords := []PayRecord{}
	page := 1

	for {
		api := fmt.Sprintf(`https://om.qq.com/account/withdrawList?page=%d&pagesize=5&index=1&num=5&relogin=1`, page)
		p.setCookie(account.GetCookie())
		bodyBytes, err := p.getReq(api)
		if err != nil {
			return nil, err
		}

		datas := QierPays{}
		if err := json.Unmarshal(bodyBytes, &datas); err != nil {
			return nil, err
		}

		for _, pay := range datas.Data.List {
			status := ""
			if pay.State == "4" {
				status = "等待付款"
			}
			if pay.State == "5" {
				status = "结算完成"
			}

			t, _ := time.Parse("2006-01-02 15:04:05", pay.CreationTime)

			if t.Before(start) {
				return payRecords, nil
			}

			amount, _ := strconv.ParseFloat(pay.TotalAmount, 32)
			payRecord := PayRecord{
				Date:              pay.CreationTime,
				ActualPayAfterTax: amount,
				Status:            status,
			}
			payRecords = append(payRecords, payRecord)
		}
	}

	return payRecords, nil
}

func (p *platqier) GetFinancialInformation(account *model.Account) (*FinancialInformation, error) {
	api := `https://om.qq.com/income/adSettleManage`
	p.setCookie(account.GetCookie())
	bodyBytes, err := p.getReq(api)
	if err != nil {
		return nil, err
	}
	doc, err := goquery.NewDocumentFromReader(bytes.NewReader(bodyBytes))
	if err != nil {
		return nil, err
	}
	financialInformation := &FinancialInformation{}
	financialInformation.BankAccountName, _ = doc.Find(`input[data-adedit-value="bank_account_name"]`).Attr("value")
	financialInformation.BankAccountNumber, _ = doc.Find(`input[data-adedit-value="bank_account_num"]`).Attr("value")
	financialInformation.BankName, _ = doc.Find(`select[data-adedit-value="bank_name"]`).Attr("rel")
	province, _ := doc.Find(`select[data-adedit-value="bank_province"]`).Attr("rel")
	city, _ := doc.Find(`select[data-adedit-value="bank_city"]`).Attr("rel")
	financialInformation.Locaiton = province + " " + city
	financialInformation.SubBank, _ = doc.Find(`input[data-adedit-value="subbank_name"]`).Attr("value")

	return financialInformation, nil
}
